﻿using System;
using Sunny.UI;
using System.IO;
using System.Linq;
using System.Drawing;
using System.Diagnostics;
using System.Windows.Forms;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Threading.Tasks;

namespace CoreShop.Library
{
    public static class DialogTool
    {
        #if DEBUG
        private static bool DEBUG = true;
#else
        private static bool DEBUG = false;
#endif
        /// <summary>
        /// 屏幕中心点
        /// </summary>
        public static Point SCREENCENTER = new Point((Screen.AllScreens[0].Bounds.Width) / 2, (Screen.AllScreens[0].Bounds.Height) / 2);
        
        /// <summary>
        /// 屏幕正上
        /// </summary>
        public static Point SCREENTOP = new Point((Screen.AllScreens[0].Bounds.Width) / 2, 0);

        /// <summary>
        /// 屏幕正down
        /// </summary>
        public static Point SCREENDOWN = new Point((Screen.AllScreens[0].Bounds.Width) / 2, Screen.AllScreens[0].Bounds.Height);
        /// <summary>
        /// 右下
        /// </summary>
        public static Point SCREENDOWNRIGHT = new Point(0, 0);

        #region 公共扩展方法

        [DllImport("gdi32.dll")]
        public static extern int CreateRoundRectRgn(int x1, int y1, int x2, int y2, int x3, int y3);

        [DllImport("user32.dll")]
        public static extern int SetWindowRgn(IntPtr hwnd, int hRgn, Boolean bRedraw);

        [DllImport("gdi32.dll", EntryPoint = "DeleteObject", CharSet = CharSet.Ansi)]
        public static extern int DeleteObject(int hObject);

        [DllImport("user32.dll")]
        public static extern int SendMessage(IntPtr hWnd, int Msg, int wParam, int lParam);

        [DllImport("user32.dll")]
        public static extern bool ReleaseCapture();

        [DllImport("user32.dll", CharSet = CharSet.Auto)]
        public static extern bool AnimateWindow(IntPtr hwnd, int dwTime, int dwFlags);

        #region 屏幕亮度
        [DllImport("dxva2.dll")]
        public static extern bool SetMonitorBrightness(IntPtr hMonitor, short brightness);

        [DllImport("dxva2.dll")]
        public static extern bool GetMonitorBrightness(IntPtr hMonitor, ref short pdwMinimumBrightness,
            ref short pdwCurrentBrightness, ref short pdwMaximumBrightness);

        [DllImport("dxva2.dll")]
        public static extern bool GetNumberOfPhysicalMonitorsFromHMONITOR(IntPtr hMonitor,
            ref uint pdwNumberOfPhysicalMonitors);

        [DllImport("dxva2.dll")]
        public static extern bool GetPhysicalMonitorsFromHMONITOR(IntPtr hMonitor,
            uint dwPhysicalMonitorArraySize, [Out] PhysicalMonitor[] pPhysicalMonitorArray);

        [DllImport("user32.dll")]
        public static extern IntPtr MonitorFromWindow([In] IntPtr hwnd, uint dwFlags);
        #endregion
        #endregion

        #region 系统参数
        public const int WM_ERASEBKGND = 0x0014;
        public const int WM_LBUTTONDOWN = 0x0201;
        public const int WM_LBUTTONUP = 0x0202;
        public const int WM_LBUTTONDBLCLK = 0x0203;
        public const int WM_WINDOWPOSCHANGING = 0x46;
        public const int WM_PAINT = 0xF;
        public const int WM_CREATE = 0x0001;
        public const int WM_ACTIVATE = 0x0006;
        public const int WM_NCCREATE = 0x0081;
        public const int WM_NCCALCSIZE = 0x0083;
        public const int WM_NCPAINT = 0x0085;
        public const int WM_NCACTIVATE = 0x0086;
        public const int WM_NCLBUTTONDOWN = 0x00A1;
        public const int WM_NCLBUTTONUP = 0x00A2;
        public const int WM_NCLBUTTONDBLCLK = 0x00A3;
        public const int WM_NCMOUSEMOVE = 0x00A0;

        public const int WM_NCHITTEST = 0x0084;

        public const int HTLEFT = 10;
        public const int HTRIGHT = 11;
        public const int HTTOP = 12;
        public const int HTTOPLEFT = 13;
        public const int HTTOPRIGHT = 14;
        public const int HTBOTTOM = 15;
        public const int HTBOTTOMLEFT = 0x10;
        public const int HTBOTTOMRIGHT = 17;
        public const int HTCAPTION = 2;
        public const int HTCLIENT = 1;

        public const int WM_FALSE = 0;
        public const int WM_TRUE = 1;

        /// <summary>
        /// 从左到右打开窗口
        /// </summary>
        public const Int32 AW_HOR_POSITIVE = 0x00000001;
        /// <summary>
        /// 从右到左打开窗口
        /// </summary>
        public const Int32 AW_HOR_NEGATIVE = 0x00000002;
        /// <summary>
        /// 从上到下打开窗口
        /// </summary>
        public const Int32 AW_VER_POSITIVE = 0x00000004;
        /// <summary>
        /// 从下到上打开窗口
        /// </summary>
        public const Int32 AW_VER_NEGATIVE = 0x00000008;
        /// <summary>
        /// 若使用了AW_HIDE标志，则使窗口向内重叠；若未使用AW_HIDE标志，则使窗口向外扩展。
        /// </summary>
        public const Int32 AW_CENTER = 0x00000010;
        /// <summary>
        /// 隐藏窗口，缺省则显示窗口。
        /// </summary>
        public const Int32 AW_HIDE = 0x00010000;
        /// <summary>
        /// 激活窗口。在使用了AW_HIDE标志后不要使用这个标志。
        /// </summary>
        public const Int32 AW_ACTIVATE = 0x00020000;
        /// <summary>
        /// 使用滑动类型。缺省则为滚动动画类型。当使用AW_CENTER标志时，这个标志就被忽略。
        /// </summary>
        public const Int32 AW_SLIDE = 0x00040000;
        /// <summary>
        /// 使用淡出效果。只有当hWnd为顶层窗口的时候才可以使用此标志。
        /// </summary>
        public const Int32 AW_BLEND = 0x00080000;
        #endregion

        /// <summary>
        /// 窗口比例
        /// </summary>
        public const float DIALOGSCALE = 0.9f;

        /// <summary>
        /// 设置窗体的圆角矩形
        /// </summary>
        /// <param name="form">需要设置的窗体</param>
        /// <param name="rgnRadius">圆角矩形的半径</param>
        public static void SetFormRadius(Form form, int rgnRadius)
        {
            int hRgn = 0;
            hRgn = CreateRoundRectRgn(0, 0, form.Width + 1, form.Height + 1, rgnRadius, rgnRadius);
            SetWindowRgn(form.Handle, hRgn, true);
            DeleteObject(hRgn);
        }

        /// <summary>
        /// 向panal添加自适应的控件
        /// </summary>
        /// <param name="userControl">指定的panal</param>
        /// <param name="productItems">添加的商品列表</param>
        /// <param name="column">多少列</param>
        /// <param name="row">多少行</param>
        /// <param name="widthPadding">间距</param>
        /// <param name="leftPadding">最左侧边距</param>
        /// <param name="one">是否只有一行</param>
        public static void AppendToPanal(UserControl userControl,
            List<UserControl> productItems,
            int column,
            int row,
            int widthPadding = 5,
            int leftPadding = 0,
            bool one = false)
        {
            userControl.Controls.Clear();
            //商品临时交换参数
            UserControl productTemp = null;
            //位置
            Point location = new Point(leftPadding, 0);
            //已添加列数数
            int countColumn = 0;
            //每一个的宽度
            int width = DialogTool.GetOneselfWidthOrHeight(userControl.Width, column, widthPadding);
            //每一个的高度
            int height = one ? userControl.Height: DialogTool.GetOneselfWidthOrHeight(userControl.Height, row, widthPadding);

            //直接添加
            for (int i = 0; i < productItems.Count; i++)
            {
                productItems[i].Width = width;
                productItems[i].Height = height;

                if (++countColumn > column)
                {
                    countColumn = 1;
                    productTemp = null;
                    location = new Point(leftPadding, location.Y);
                    location.Y += productItems[i].Height;
                    location.Y += widthPadding;
                }

                if (productTemp != null)
                {
                    location.X += productItems[i].Width;
                    location.X += widthPadding;
                }

                productItems[i].Location = location;
                productTemp = productItems[i];

                userControl.Controls.Add(productItems[i]);
            }
        }

        /// <summary>
        /// 关闭当前程序
        /// 获取当前程序名称:
        ///     System.Reflection.Assembly.GetExecutingAssembly().GetName().Name
        /// </summary>
        /// <param name="name">程序进程名称</param>
        public static void StartApplicationKill(string name)
        {
            PublicInvokeTool.SelfProcessExit();
            Process[] pro = Process.GetProcessesByName(name);
            if (pro.Length > 0)
            {
                pro[0].Kill();
            }
        }

        /// <summary>
        /// 关闭当前程序
        /// 获取当前程序名称:
        ///     System.Reflection.Assembly.GetExecutingAssembly().GetName().Name
        /// </summary>
        /// <param name="name">程序进程名称</param>
        public static void ApplicationKill(string name)
        {
            CloseAiExe();
            if (name.Contains("CoreShop")) 
            {
                PublicInvokeTool.SelfProcessExit();
            }
            Process[] pro = Process.GetProcessesByName(name);
            //if (pro.Length > 0)
            //{
            //    pro[0].Kill();
            //}

            foreach (var process in pro)
            {
                // 关闭当前进程及其所有子进程

                // 获取当前进程的所有子进程
                var childProcesses = GetChildProcesses(process.Id);
                // 关闭所有子进程
                foreach (var childProcess in childProcesses)
                {
                    if (childProcess.MainWindowHandle != IntPtr.Zero)
                    {
                        childProcess.CloseMainWindow();
                    }
                    // 如果进程仍然存在，则强制关闭
                    if (!childProcess.HasExited)
                    {
                        childProcess.Kill();
                    }
                }
                process.Kill();
            }
        }
        private static Process[] GetChildProcesses(int parentId)
        {
            using (var searcher = new System.Management.ManagementObjectSearcher(
                "SELECT * FROM Win32_Process WHERE ParentProcessId=" + parentId))
            {
                var childProcesses = new List<Process>();

                foreach (var obj in searcher.Get())
                {
                    int processId = Convert.ToInt32(obj["ProcessId"]);
                    Process process = Process.GetProcessById(processId);
                    childProcesses.Add(process);
                }

                return childProcesses.ToArray();
            }
        }


        /// <summary>
        /// 关闭AI程序
        /// </summary>
        private static void CloseAiExe() 
        {
            // 使用进程名称（不带.exe）
            Process[] processes = Process.GetProcessesByName("craft_cata_32");

            if (processes.Length > 0)
            {
                foreach (Process process in processes)
                {
                    try
                    {
                        process.Kill();
                        process.WaitForExit();
                        // 等待进程退出（可选）
                    }
                    catch (Exception ex)
                    {
                       //Log.LogManage.Error($"终止进程时出错: {ex.Message}");
                    }
                }
            }
            else
            {
                //Console.WriteLine("进程未运行。");
            }
        }


        /// <summary>
        /// 启动应用
        /// </summary>
        /// <param name="name"></param>
        public static void ApplicationStart(string name)
        {
            try
            {
                Process.Start(name);
            }
            catch (Exception ex)
            {
                //LogManage.Error($"ApplicationStart,{ex.Message},{name}");
            }
        }


        /// <summary>
        /// 编译模式
        /// </summary>
        public static bool EditingPatternForDebug()
        {
            return DEBUG;
        }

        /// <summary>
        /// 获取单个商品框的宽度或高度
        /// </summary>
        /// <param name="width">总宽度</param>
        /// <param name="count">一行或一列个数</param>
        /// <param name="widthPadding">边距</param>
        /// <returns></returns>
        public static int GetOneselfWidthOrHeight(float widthOrHeight, int count, int widthPadding = 5)
        {
            widthOrHeight -= (widthPadding * count);
            
            return Int32.Parse(Math.Round(widthOrHeight / count, 0).ToString());
        }
                

        
        /// <summary>
        /// 深拷贝分类
        /// </summary>
        /// <param name="items"></param>
        /// <returns></returns>
        public static List<object> DeepCopyItems(List<object> items)
        {
            List<object> itemsCopy =
                    new List<object>();
            //深拷贝
            items.ForEach(item2sItem =>
            {
                itemsCopy.Add(item2sItem);
            });

            return itemsCopy;
        }

        /// <summary>
        /// 设置窗口打开动画
        /// </summary>
        /// <param name="hwnd">窗口句柄</param>
        /// <param name="dwTime">打开时间</param>
        /// <param name="dwFlags">打开类型</param>
        public static void SetWindowOpenAnimate(IntPtr hwnd, int dwTime, int dwFlags)
        {
            AnimateWindow(hwnd, dwTime, dwFlags);
        }

        /// <summary>
        /// 设置屏幕亮度
        /// </summary>
        /// <param name="handle">所在屏幕窗口的句柄</param>
        /// <param name="brightness">亮度</param>
        /// <returns></returns>
        public static bool SetBrightness(IntPtr handle, short brightness)
        {
            if (handle == IntPtr.Zero)
            {
                return false;
            }

            uint pdwNumberOfPhysicalMonitors = uint.MinValue;
            //获取屏幕所在的屏幕设备
            var hMonitor = MonitorFromWindow(handle, 1);
            GetNumberOfPhysicalMonitorsFromHMONITOR(hMonitor, ref pdwNumberOfPhysicalMonitors);
            var screen = new PhysicalMonitor[pdwNumberOfPhysicalMonitors];
            GetPhysicalMonitorsFromHMONITOR(hMonitor, pdwNumberOfPhysicalMonitors, screen);

            return screen.Length <= 0 ? false : SetMonitorBrightness(screen[0].hPhysicalMonitor, brightness);
        }

        /// <summary>
        /// 得到屏幕亮度参数
        /// </summary>
        /// <param name="handle">所在屏幕窗口的句柄</param>
        /// <param name="minBrightness">最小亮度</param>
        /// <param name="currentBrightness">当前亮度</param>
        /// <param name="maxBrightness">最大亮度</param>
        /// <returns></returns>
        public static bool GetBrightness(IntPtr handle, ref short minBrightness,
            ref short currentBrightness,
            ref short maxBrightness)
        {
            if (handle == IntPtr.Zero)
            {
                return false;
            }

            uint pdwNumberOfPhysicalMonitors = uint.MinValue;
            //获取屏幕所在的屏幕设备
            var hMonitor = MonitorFromWindow(handle, 1);
            GetNumberOfPhysicalMonitorsFromHMONITOR(hMonitor, ref pdwNumberOfPhysicalMonitors);
            var screen = new PhysicalMonitor[pdwNumberOfPhysicalMonitors];
            GetPhysicalMonitorsFromHMONITOR(hMonitor, pdwNumberOfPhysicalMonitors, screen);

            return screen.Length <= 0 ? false : GetMonitorBrightness(screen[0].hPhysicalMonitor, ref minBrightness,
                ref currentBrightness,
                ref maxBrightness);
        }
    }

    /// <summary>
    /// 物理常量
    /// </summary>
    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    public struct PhysicalMonitor
    {
        public IntPtr hPhysicalMonitor;

        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)]
        public string szPhysicalMonitorDescription;
    }
}
